﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartSpace.Core
{
    public partial class CoreService : ICoreService
    {
        public PagedList<Role> GetRoles(int start, int limit)
        {
            using (CoreContext context = _contextFactory.Get())
            {
                List<Role> roles = context.Set<Role>()
                    .OrderByDescending(p => p.CreatedTime)
                    .Skip(start)
                    .Take(limit)
                    .ToList();
                PagedList<Role> pagedRoles = new PagedList<Role>();
                foreach (Role role in roles)
                {
                    pagedRoles.Add(role);
                }
                pagedRoles.Start = start;
                pagedRoles.Limit = limit;
                pagedRoles.Total = context.Set<Role>().Count();

                return pagedRoles;
            }
        }

        public bool SaveRole(Role role)
        {
            using (CoreContext context = _contextFactory.Get())
            {
                if (context.Set<Role>()
                    .Where(p => p.Id == role.Id)
                    .Select(p => p.Id)
                    .FirstOrDefault() == default(Guid))
                {
                    context.Set<Role>().Add(role);
                }
                else
                {
                    context.Entry(role).State = System.Data.Entity.EntityState.Modified;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        public bool DeleteRole(Role role)
        {
            using (CoreContext context = _contextFactory.Get())
            {
                if (context.Set<Role>()
                    .Where(p => p.Id == role.Id)
                    .Select(p => new { p.Id })
                    .FirstOrDefault() != null)
                {
                    context.Entry(role).State = System.Data.Entity.EntityState.Deleted;
                }
                context.SaveChanges();
                return true;
            }
        }

        public bool DeleteRole(Guid roleId)
        {
            using (CoreContext context = _contextFactory.Get())
            {
                Role role = context.Set<Role>()
                    .Where(p => p.Id == roleId)
                    .FirstOrDefault();
                if (role != null)
                {
                    context.Entry(role).State = System.Data.Entity.EntityState.Deleted;
                }
                context.SaveChanges();
                return true;
            }
        }

        public bool AssignRoleToUser(Role role, User user, bool isMajor)
        {
            using (CoreContext context = _contextFactory.Get())
            {
                UserRole userRole = new UserRole();
                userRole.Id = Guid.NewGuid();
                userRole.UserId = user.Id;
                userRole.RoleId = role.Id;
                userRole.IsMajor = isMajor;

                if (context.Set<UserRole>().Where(p => p.UserId == user.Id && p.RoleId == role.Id).Select(p => p.Id)
                    .SingleOrDefault() == default(Guid))
                {
                    context.Set<UserRole>().Add(userRole);
                    if (context.SaveChanges() > 0)
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        public bool RemoveRoleFromUser(Guid roleId, Guid userId)
        {
            using (CoreContext context = _contextFactory.Get())
            {
                UserRole userRole = context.Set<UserRole>().Where(p => p.UserId == userId && p.RoleId == roleId).SingleOrDefault();

                if (userRole != null)
                {
                    context.Entry(userRole).State = System.Data.Entity.EntityState.Deleted;

                    if (context.SaveChanges() > 0)
                    {
                        return true;
                    }
                    return false;
                }
                return true;
            }
        }

        public bool RemoveRoleFromUser(Guid roleId, string account)
        {
            using (CoreContext context = _contextFactory.Get())
            {
                UserRole userRole = context.Set<UserRole>()
                    .Join(context.Set<User>().Where(p=>p.Account == account),
                        l=>l.UserId,
                        r=>r.Id,
                        (l,r)=>l).SingleOrDefault();

                if (userRole != null)
                {
                    context.Entry(userRole).State = System.Data.Entity.EntityState.Deleted;

                    if (context.SaveChanges() > 0)
                    {
                        return true;
                    }
                    return false;
                }
                return true;
            }
        }

        public PagedList<User> GetUserListByRole(Guid roleId, int start, int limit)
        {
            using (CoreContext context = _contextFactory.Get())
            {
                List<User> users = context.Set<User>()
                    .Join(context.Set<UserRole>().Where(p=>p.RoleId == roleId),
                        l=>l.Id,
                        r=>r.UserId,
                        (l,r)=>l)
                    .OrderBy(p => p.Account)
                    .Take(limit)
                    .Skip(start)
                    .ToList();
                int total = context.Set<User>()
                    .Join(context.Set<UserRole>().Where(p => p.RoleId == roleId),
                        l => l.Id,
                        r => r.UserId,
                        (l, r) => l).Count();
                PagedList<User> pagedList = new PagedList<User>();
                pagedList.AddRange(users);
                pagedList.Start = start;
                pagedList.Limit = limit;
                pagedList.Total = total;

                return pagedList;
            }
        }

        public List<Role> GetRoleListByUser(Guid userId)
        {
            using (CoreContext context = _contextFactory.Get())
            {
                return context.Set<UserRole>().Where(p => p.UserId == userId)
                    .Select(p => p.Role)
                    .OrderBy(p => p.Name)
                    .ToList();
            }
        }

        public List<Role> GetRoleListByUser(string account)
        {
            using (CoreContext context = _contextFactory.Get())
            {
                return context.Set<UserRole>()
                    .Join(context.Set<User>().Where(p => p.Account == account),
                        l => l.UserId,
                        r => r.Id,
                        (l, r) => l)
                    .Select(p => p.Role)
                    .OrderBy(p => p.Name)
                    .ToList();
            }
        }
    }
}
